﻿using System.Collections;
using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class MetadataFieldValueRangeList : SyntaxNode, IReadOnlyList<MetadataFieldValueRange>
{
    private SyntaxToken? _leftBracketToken;
    private SyntaxList<MetadataFieldValueRange>? _ranges;
    private SyntaxToken? _rightBracketToken;

    internal MetadataFieldValueRangeList(SyntaxNode? parent) :
        base(SyntaxKinds.MetadataFieldValueRangeList, parent)
    {
    }


    public SyntaxToken? LeftBracketToken => _leftBracketToken;

    public SyntaxToken? RightBracketToken => _rightBracketToken;


    public int Count => _ranges?.Count ?? 0;


    public MetadataFieldValueRange this[int index]
    {
        get
        {
            if (_ranges == null)
            {
                throw new IndexOutOfRangeException(nameof(index));
            }

            return _ranges[index];
        }
    }


    public IEnumerator<MetadataFieldValueRange> GetEnumerator()
    {
        return _ranges?.GetEnumerator() ?? Enumerable.Empty<MetadataFieldValueRange>().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    public MetadataFieldValueRangeList Update(SyntaxToken? leftBracket, SyntaxToken? rightBracket)
    {
        SetChildNullableField(ref _leftBracketToken, SyntaxToken.IsNullOrEmpty, leftBracket);
        SetChildNullableField(ref _rightBracketToken, SyntaxToken.IsNullOrEmpty, rightBracket);
        return this;
    }


    public MetadataFieldValueRangeList Update(IEnumerable<MetadataFieldValueRange> ranges)
    {
        foreach (MetadataFieldValueRange range in ranges)
        {
            AddChildMember(ref _ranges, range);
        }

        return this;
    }


    public MetadataFieldValueRangeList Update(SyntaxToken leftBracket, IEnumerable<MetadataFieldValueRange> ranges,
        SyntaxToken rightBracket)
    {
        SetChildNullableField(ref _leftBracketToken, SyntaxToken.IsNullOrEmpty, leftBracket);
        SetChildNullableField(ref _rightBracketToken, SyntaxToken.IsNullOrEmpty, rightBracket);
        foreach (MetadataFieldValueRange range in ranges)
        {
            AddChildMember(ref _ranges, range);
        }

        return this;
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, LeftBracketToken, RightBracketToken);
        AcceptList(visitor, _ranges);
    }
}


public static partial class NodeFactory
{
    public static MetadataFieldValueRangeList CreateMetadataFieldValueRangeList(SyntaxNode? parent,
        SyntaxToken? leftBracketToken, SyntaxToken? rightBracketToken, IEnumerable<MetadataFieldValueRange>? ranges)
    {
        Debug.Assert(leftBracketToken == null || leftBracketToken.IsNode(SyntaxKinds.LeftBracketToken));
        Debug.Assert(rightBracketToken == null || rightBracketToken.IsNode(SyntaxKinds.RightBracketToken));
        MetadataFieldValueRangeList list = new(parent);
        list.Update(leftBracketToken, rightBracketToken);
        if (ranges != null)
        {
            list.Update(ranges);
        }

        return list;
    }
}